package com.eapi.project.controller;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.eapi.project.common.DeleteRequest;
import com.eapi.project.common.ResultUtils;
import com.eapi.project.exception.BusinessException;
import com.eapi.project.model.dto.user.*;
import com.eapi.project.model.entity.Collectrecord;
import com.eapi.project.model.entity.Identifycode;
import com.eapi.project.model.entity.Likerecord;
import com.eapi.project.model.entity.Paybill;
import com.eapi.project.model.enums.PayStatusEnum;
import com.eapi.project.model.vo.UserVO;
import com.eapi.project.service.*;
import com.eapi.project.utils.AliPayApiUtils;
import com.eapi.project.utils.AliPayQuryApiUtils;
import com.eapi.project.utils.alioss.AliOSSDeleteUtils;
import com.eapi.project.utils.alioss.FileNameFromUrl;
import com.eapi.eapicommom.model.entity.InterfaceInfo;
import com.eapi.eapicommom.model.entity.User;
import com.eapi.project.common.BaseResponse;
import com.eapi.project.common.ErrorCode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.MalformedURLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户接口
 *
 * @author yupi
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private CollectrecordService collectrecordService;


    @Resource
    private LikerecordService likerecordService;

    @Resource
    private InterfaceInfoService interfaceInfoService;

    @Resource
    private AliOSSDeleteUtils aliOSSDeleteUtils;

    @Resource
    private PaybillService paybillService;

    @Resource IdentifycodeService identifycodeService;
    // region 登录相关

    /**
     * 用户注册
     *
     * @param userRegisterRequest
     * @return
     */
    @PostMapping("/register")
    public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
        if (userRegisterRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        String emailAddress = userRegisterRequest.getEmailAddress();
        String identifyCode = userRegisterRequest.getIdentifyCode();
        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword, emailAddress, identifyCode)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请按规范格式填写");
        }
        long result = userService.userRegister(userAccount, userPassword, checkPassword, emailAddress, identifyCode);
        return ResultUtils.success(result);
    }

    /**
     * 用户登录
     *
     * @param userLoginRequest
     * @param request
     * @return
     */
    @PostMapping("/login")
    public BaseResponse<User> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        if (userLoginRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.userLogin(userAccount, userPassword, request);
        return ResultUtils.success(user);
    }

    @PostMapping("/loginbyemail")
    public BaseResponse<User> userLoginByEmail(@RequestBody UserLoginByEmailRequest userLoginByEmailRequest, HttpServletRequest request) {
        if (userLoginByEmailRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String emailAddress = userLoginByEmailRequest.getEmailAddress();
        String identifyCode = userLoginByEmailRequest.getIdentifyCode();
        if (StringUtils.isAnyBlank(emailAddress, identifyCode)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱或验证码不能为空");
        }
        User user = userService.userLoginByEmail(emailAddress, identifyCode, request);
        return ResultUtils.success(user);
    }


    /**
     * 用户注销
     *
     * @param request
     * @return
     */
    @PostMapping("/logout")
    public BaseResponse<Boolean> userLogout(HttpServletRequest request) {
        if (request == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = userService.userLogout(request);
        return ResultUtils.success(result);
    }

    /**
     * 获取当前登录用户
     *
     * @param request
     * @return
     */
    @GetMapping("/get/login")
    public BaseResponse<UserVO> getLoginUser(HttpServletRequest request) {
        User user = userService.getLoginUser(request);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return ResultUtils.success(userVO);
    }

    // endregion

    // region 增删改查

    /**
     * 创建用户
     *
     * @param userAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addUser(@RequestBody UserAddRequest userAddRequest, HttpServletRequest request) {
        if (userAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = new User();
        BeanUtils.copyProperties(userAddRequest, user);
        boolean result = userService.save(user);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return ResultUtils.success(user.getId());
    }

    /**
     * 删除用户
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = userService.removeById(deleteRequest.getId());
        return ResultUtils.success(b);
    }

    /**
     * 更新用户
     *
     * @param userUpdateRequest
     * @param request
     * @return
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateRequest userUpdateRequest, HttpServletRequest request) throws MalformedURLException {
        if (userUpdateRequest == null || userUpdateRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User existUser = userService.getById(userUpdateRequest.getId());
        User user = new User();
        BeanUtils.copyProperties(userUpdateRequest, user);
        String tempPassword = userUpdateRequest.getUserPassword();
        if (tempPassword == null) { // 如果不修改密码，则保留原密码
            user.setUserPassword(existUser.getUserPassword());
        } else { // 如果要修改密码
            String userPassword = user.getUserPassword();
            String encryptPassword = DigestUtils.md5DigestAsHex(("yupi" + userPassword).getBytes());
            user.setUserPassword(encryptPassword);
        }
        // 判断用户头像是否为空
        String userAvatar = existUser.getUserAvatar();
        if (userAvatar != null && user.getUserAvatar() != null) {
            String fileName = FileNameFromUrl.getFileNameFromUrl(userAvatar);
            aliOSSDeleteUtils.deleteFile(fileName);
        }
        //System.out.println(user);
        boolean result = userService.updateById(user);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取用户
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/get")
    public BaseResponse<UserVO> getUserById(int id, HttpServletRequest request) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getById(id);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return ResultUtils.success(userVO);
    }


    /**
     * 获取用户列表
     *
     * @param userQueryRequest
     * @param request
     * @return
     */
    @GetMapping("/list")
    public BaseResponse<List<UserVO>> listUser(UserQueryRequest userQueryRequest, HttpServletRequest request) {
        User userQuery = new User();
        if (userQueryRequest != null) {
            BeanUtils.copyProperties(userQueryRequest, userQuery);
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(userQuery);
        List<User> userList = userService.list(queryWrapper);
        List<UserVO> userVOList = userList.stream().map(user -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }).collect(Collectors.toList());
        return ResultUtils.success(userVOList);
    }

    /**
     * 分页获取用户列表
     *
     * @param userQueryRequest
     * @param request
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<UserVO>> listUserByPage(UserQueryRequest userQueryRequest, HttpServletRequest request) {
        long current = 1;
        long size = 10;
        User userQuery = new User();
        if (userQueryRequest != null) {
            BeanUtils.copyProperties(userQueryRequest, userQuery);
            current = userQueryRequest.getCurrent();
            size = userQueryRequest.getPageSize();
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(userQuery);
        Page<User> userPage = userService.page(new Page<>(current, size), queryWrapper);
        Page<UserVO> userVOPage = new PageDTO<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        List<UserVO> userVOList = userPage.getRecords().stream().map(user -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }).collect(Collectors.toList());
        userVOPage.setRecords(userVOList);
        return ResultUtils.success(userVOPage);
    }

    // endregion

    /*    @PostMapping("/buyPoints")
        public BaseResponse<String> buyPoints(@RequestBody UserBuyPointsRequest userBuyPointsRequest, HttpServletRequest request) {
            if (userBuyPointsRequest == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            User loginUser = userService.getLoginUser(request);
            boolean b = userService.buyPoints(userBuyPointsRequest, loginUser.getId());
            if (b) {
                return ResultUtils.success("购买成功");
            } else {
                return ResultUtils.error(ErrorCode.OPERATION_ERROR);
            }
        }*/
    @PostMapping("/buyPoints")
    public BaseResponse<String> buyPoints(@RequestBody AliPayRequest aliPayRequest, HttpServletRequest request) {
        if (aliPayRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        String result = AliPayApiUtils.AliPay(aliPayRequest);
        return ResultUtils.success(result);
    }

/*    @PostMapping("/beVip")
    public BaseResponse<String> beVip(@RequestBody AliPayRequest aliPayRequest, HttpServletRequest request) {
        if (aliPayRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        String result = AliPayApiUtils.AliPay(aliPayRequest);
        return ResultUtils.success(result);
    }*/

    @PostMapping("/isPay")
    public BaseResponse<String> isPay(@RequestBody AliPayQuryRequest aliPayQuryRequest,HttpServletRequest request) throws ParseException {
        // 查询支付
        AliPayQuryApiUtils aliPayQuryApiUtils = new AliPayQuryApiUtils();
        // aliPayQuryRequest.setOut_trade_no("vnajknvdjka");//vnajknvdjka
        // aliPayQuryRequest.setOut_trade_no(aliPayQuryRequest.getOut_trade_no());
        String result = aliPayQuryApiUtils.payQury(aliPayQuryRequest);
        // 从result中获取交易代码，判断是否成功
        JSONObject reply = JSONUtil.parseObj(result);
        String alipayTradeQueryResponse = reply.getStr("alipay_trade_query_response");
        JSONObject entries = JSONUtil.parseObj(alipayTradeQueryResponse);
        String code = entries.getStr("code");
        if(!code.equals("10000")) throw new BusinessException(ErrorCode.PARAMS_ERROR,"交易失败，请检查是否支付成功，如有问题请联系客服");
        // 交易金额
        String amount = entries.getStr("total_amount");
        // 交易时间
        String payDateString = entries.getStr("send_pay_date");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date payDate= sdf.parse(payDateString);
        // todo 添加支付流水信息，修改用户剩余积分
        User loginUser = userService.getLoginUser(request);
        // 存储流水信息
        Paybill paybill = new Paybill();
        paybill.setUserId(loginUser.getId());
        paybill.setOrderId(aliPayQuryRequest.getOut_trade_no());
        paybill.setPayamount(Double.parseDouble(amount));
        paybill.setStatus(PayStatusEnum.PAYSUCCESS.getValue());
        paybill.setCreatetime(payDate);
        paybill.setUsername(loginUser.getUserName() == null ? loginUser.getUserAccount() : loginUser.getUserName());
        paybillService.save(paybill);
        int points = (int)(Double.parseDouble(amount)*10 + Double.parseDouble(amount)*10/8);
        // 40004 交易不存在 10000 交易成功
        // 修改用户剩余几分数
        boolean b = userService.buyPoints(points, loginUser.getId());
        // System.out.println(result);
        return ResultUtils.success("交易成功");
    }


    @PostMapping("/isVipPay")
    public BaseResponse<String> isVipPay(@RequestBody WAliPayQuryRequest waliPayQuryRequest,HttpServletRequest request) throws ParseException {
        // 查询支付
        int vip = waliPayQuryRequest.getVip();
        AliPayQuryRequest aliPayQuryRequest = new AliPayQuryRequest();
        aliPayQuryRequest.setOut_trade_no(waliPayQuryRequest.getOut_trade_no());
        AliPayQuryApiUtils aliPayQuryApiUtils = new AliPayQuryApiUtils();
        // aliPayQuryRequest.setOut_trade_no("vnajknvdjka");//vnajknvdjka
        // aliPayQuryRequest.setOut_trade_no(aliPayQuryRequest.getOut_trade_no());
        String result = aliPayQuryApiUtils.payQury(aliPayQuryRequest);
        // 从result中获取交易代码，判断是否成功
        JSONObject reply = JSONUtil.parseObj(result);
        String alipayTradeQueryResponse = reply.getStr("alipay_trade_query_response");
        JSONObject entries = JSONUtil.parseObj(alipayTradeQueryResponse);
        String code = entries.getStr("code");
        if(!code.equals("10000")) throw new BusinessException(ErrorCode.PARAMS_ERROR,"交易失败，请检查是否支付成功，如有问题请联系客服");
        // 交易金额
        String amount = entries.getStr("total_amount");
        // 交易时间
        String payDateString = entries.getStr("send_pay_date");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date payDate= sdf.parse(payDateString);
        User loginUser = userService.getLoginUser(request);
        // 存储流水信息
        Paybill paybill = new Paybill();
        paybill.setUserId(loginUser.getId());
        paybill.setOrderId(aliPayQuryRequest.getOut_trade_no());
        double doubleAmount = Double.parseDouble(amount);
        paybill.setPayamount(doubleAmount);
        paybill.setStatus(PayStatusEnum.PAYSUCCESS.getValue());
        paybill.setCreatetime(payDate);
        paybill.setUsername(loginUser.getUserName() == null ? loginUser.getUserAccount() : loginUser.getUserName());
        paybillService.save(paybill);
        // 40004 交易不存在 10000 交易成功
        // 修改用户VIP状态
        int[] vipAry = {0,1,2,3,4};
        loginUser.setVip(vipAry[vip]);
        userService.updateById(loginUser);
        return ResultUtils.success("会员充值成功");
    }

    /**
     * 重新获取accesskey和secretkey
     */
    @PostMapping("/changeAk")
    public BaseResponse<String> changeAkandSk(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        String userAccount = loginUser.getUserAccount();
        String SALT = "yupi";
        String accessKey = DigestUtil.md5Hex(SALT + userAccount + RandomUtil.randomNumbers(5));
        String secretKey = DigestUtil.md5Hex(SALT + userAccount + RandomUtil.randomNumbers(8));
        loginUser.setAccessKey(accessKey);
        loginUser.setSecretKey(secretKey);
        boolean isUpdate = userService.updateById(loginUser);
        if (isUpdate) {
            return ResultUtils.success("获取成功");
        } else {
            return ResultUtils.error(ErrorCode.OPERATION_ERROR);
        }
    }

    /**
     * 用户成查看自己收藏的接口
     *
     * @param request
     * @return
     */
    @GetMapping("getCollections")
    public BaseResponse<List<InterfaceInfo>> getCollections(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        Long userId = loginUser.getId();
        QueryWrapper<Collectrecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);
        List<Collectrecord> list = collectrecordService.list(queryWrapper);
        List<InterfaceInfo> interfaceInfoList = new ArrayList<>();
        // 遍历获取接口信息
        for (Collectrecord collectrecord : list) {
            Long interfaceInfoId = collectrecord.getInterfaceInfoId();
            interfaceInfoList.add(interfaceInfoService.getById(interfaceInfoId));
        }
        return ResultUtils.success(interfaceInfoList);
    }

    @GetMapping("getLikes")
    public BaseResponse<List<InterfaceInfo>> getLikes(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        Long userId = loginUser.getId();
        QueryWrapper<Likerecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);
        List<Likerecord> list = likerecordService.list(queryWrapper);
        List<InterfaceInfo> interfaceInfoList = new ArrayList<>();
        // 遍历获取接口信息
        for (Likerecord likeRecord : list) {
            Long interfaceInfoId = likeRecord.getInterfaceInfoId();
            interfaceInfoList.add(interfaceInfoService.getById(interfaceInfoId));
        }
        return ResultUtils.success(interfaceInfoList);
    }

    /**
     * 查询充值记录
     */
    @GetMapping("getPaybill")
    public BaseResponse<List<Paybill>> getPaybill(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        QueryWrapper<Paybill> query = new QueryWrapper<>();
        query.eq("userId", loginUser.getId());
        List<Paybill> list = paybillService.list(query);
        return ResultUtils.success(list);
    }

    /**
     * 获取支付总金额
     * @param request
     * @return
     */
    @GetMapping("getPaySum")
    public BaseResponse<Double> getPaySum(HttpServletRequest request){
        User loginUser = userService.getLoginUser(request);
        QueryWrapper<Paybill> query = new QueryWrapper<>();
        query.eq("userId", loginUser.getId());
        List<Paybill> list = paybillService.list(query);
        double sum = 0;
        for (int i = 0; i < list.size(); i++) {
            sum+=list.get(i).getPayamount();
        }
        return ResultUtils.success(sum);
    }

    @PostMapping("forgetPassWord")
    public BaseResponse<String> forgetPassWord(@RequestBody UserForgetPasswordRequest userForgetPasswordRequest){
        if (userForgetPasswordRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String emailAddress = userForgetPasswordRequest.getEmailAddress();
        String identifyCode = userForgetPasswordRequest.getIdentifyCode();
        String newPassWord = userForgetPasswordRequest.getNewPassword();
        if (StringUtils.isAnyBlank(emailAddress, identifyCode)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱或验证码不能为空");
        }
        if (StringUtils.isAnyBlank(newPassWord)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "新密码不能为空");
        }
        // 判断验证码是否正确
        QueryWrapper<Identifycode> inentifyQueryWrapper = new QueryWrapper<>();
        inentifyQueryWrapper.eq("emailaddress", emailAddress);
        Identifycode inentify = identifycodeService.getOne(inentifyQueryWrapper); // 查询验证码
        String correctIdentifyCode = inentify.getIdentifycode();
        if (!identifyCode.equals(correctIdentifyCode)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("emailAddress", emailAddress);
        User user = userService.getOne(queryWrapper);
        String encryptPassword = DigestUtils.md5DigestAsHex(("yupi" + newPassWord).getBytes());
        user.setUserPassword(encryptPassword);
        userService.updateById(user);
        return ResultUtils.success("修改成功");
    }


}
